package cn.hy.controller;


import cn.hy.param.UserParam;
import cn.hy.response.R;
import cn.hy.validate.group.EditValidationGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

/**
 *
 *  @Validated和@Valid什么区别？
 *
 *   在检验Controller的入参是否符合规范时，使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同：
 *
 *      分组 @Validated：提供了一个分组功能，可以在入参验证时，根据不同的分组采用不同的验证机制，这个网上也有资料，不详述。@Valid：作为标准JSR-303规范，还没有吸收分组的功能。
 *      注解地方 @Validated：可以用在类型、方法和方法参数上。但是不能用在成员属性（字段）上 @Valid：可以用在方法、构造函数、方法参数和成员属性（字段）上
 *      嵌套类型 比如本文例子中的address是user的一个嵌套属性, 只能用@Valid
 *
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * http://localhost:8080/user/add .
     *
     * @param userParam user param
     * @return user
     */
    @PostMapping("add")
    public R<String> add(@Valid @RequestBody UserParam userParam, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<ObjectError> errors = bindingResult.getAllErrors();
            errors.forEach(p -> {
                FieldError fieldError = (FieldError) p;
                log.error("Invalid Parameter : object - {},field - {},errorMessage - {}", fieldError.getObjectName(),
                        fieldError.getField(), fieldError.getDefaultMessage());
            });
            return R.fail("invalid parameter");
        }
        return R.success();
    }


    /**
     * http://localhost:8080/user/add .
     *
     * @param userParam user param
     * @return user
     */
    @PostMapping("edit")
    public R<UserParam> edit(@Validated(EditValidationGroup.class) @RequestBody UserParam userParam) {
        return R.success(userParam);
    }
}
